/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */
#pragma once

#include <noise/hard/Hardware.h>
#include <dsound.h>
#include <threads/Thread.h>
#include <threads/Lock.h>
#include <math/Vector3.h>
#include "Channel.h"

namespace liba {
namespace noise {
namespace hard {
namespace directx8 {

class Hardware : public hard::Hardware
{
public:
	Hardware(IDirectSound8 * lpds, IDirectSoundBuffer * primary_buffer);
	virtual ~Hardware();
	virtual hard::Channel * create_static_channel( const Atom & channel_type, const filesystem::String & name);
	virtual hard::Channel * create_streaming_channel( const Atom & channel_type );
	virtual std::string get_name()const
	{
		return std::string("directx8");
	}

	void life_cycle( double delta_time );
	const DSCAPS & get_caps()const
	{
		return caps;
	}
	IDirectSound8 * get_device()const
	{
		return lpds;
	}
	static int convert_linear_volume(double value);

	void play_static_3d_channel(ChannelStatic * channel)
	{
		playing_channels.push_back(channel);
	}
	void stop_static_3d_channel(ChannelStatic * channel)
	{
		playing_channels.remove(channel);
	}
	void add_static_channel(ChannelStatic * channel)
	{
		static_channels.push_back(channel);
	}
	void remove_static_channel(ChannelStatic * channel)
	{
		static_channels.remove(channel);
	}
	void add_streaming_channel(ChannelStreaming * channel)
	{
		streaming_channels.push_back(channel);
	}
	void remove_streaming_channel(ChannelStreaming * channel)
	{
		streaming_channels.remove(channel);
	}
private:
	typedef std::list<ChannelStatic *> ChannelStaticList;
	ChannelStaticList playing_channels;
	ChannelStaticList static_channels;
	typedef std::list<ChannelStreaming *> ChannelStreamingList;
	ChannelStreamingList streaming_channels;
	int max_playing_channels;
	void ListenerPositionChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerPosition;
	void ListenerSpeedChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerSpeed;
	properties::DependencyProperty<math::Vector3<float> > listenerFront;
	properties::DependencyProperty<math::Vector3<float> > listenerUp;

	void ExactVolumeChanged(double value);
	properties::DependencyProperty<double> exactVolume;
	DSCAPS caps;
	IDirectSound8 * lpds;
	IDirectSoundBuffer * primary_buffer;
	IDirectSound3DListener * listener;
	LPKSPROPERTYSET prop;
};

} // namespace directx8
} // namespace hard
} // namespace noise
} // namesapce liba
using namespace liba;

